<!-- Copyright 2013 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -->
<!DOCTYPE html>
<title>Integration tests for end-to-end use.</title>
<script src="../../closure/base.js"></script>
<script src="test_js_deps-runfiles.js"></script>
<script>
  goog.require('goog.testing.jsunit');
  goog.require('goog.testing.AsyncTestCase');
  goog.require('e2e');
  goog.require('e2e.cipher.all');
  goog.require('e2e.compression.all');
  goog.require('e2e.openpgp.asciiArmor');
  goog.require('e2e.openpgp.parse');
  goog.require('e2e.openpgp.block.all');
  goog.require('e2e.openpgp.block.factory');
  goog.require('e2e.openpgp.packet.all');
  goog.require('e2e.hash.all');
  goog.require('e2e.signer.all');
</script>
<script>
var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall(document.title);

/**
 * Tests decryption with message and keys generated by gpg.
 * Uses RSA, iterated S2K, AES, and ZLIB.
 */
function testDecryption() {
  var key =
    '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    '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\n' +
    '1KwNtVw=\n' +
    '=wHzz\n' +
    '-----END PGP PRIVATE KEY BLOCK-----';
  var privateKeyBlock = e2e.openpgp.block.factory.parseAscii(key);

  var passphrase = e2e.stringToByteArray('test');
  // Main key doesn't have what we want, but decrypt it anyways:
  privateKeyBlock.keyPacket.cipher.unlockKey(passphrase);
  privateKeyBlock.packets[3].cipher.unlockKey(passphrase);
  var message =
    '-----BEGIN PGP MESSAGE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'hIwDXrdcIWJXR5IBA/92aAG/zps/vIGXdw5TEEpjjJsTzzb9q+YPtmrWMBn/dvf2\n' +
    't3RzxFigHvOTZxQthlGYr5Ft8zxmG4l7T6QO+sYp+sQuHjiex1w6A6fuNVx8ieXD\n' +
    'G/MGU16PhBa6wLe0OOEE5nmEKYo1A8imHUyvFF8VXpDeMgACHYBFKvA/4bIbANJQ\n' +
    'ARBHsOBARkRDW7TibAaXijDaFBKGCylxi8dxQVCDkDJpzLDcs1JsiE6v4eKVztb8\n' +
    'msKSPseUtmsJdu9oQyZdFU4igAWSRKvXQOXAbjBdgmw=\n' +
    '=HSJn\n' +
    '-----END PGP MESSAGE-----';
  var messageBlock = e2e.openpgp.block.factory.parseAscii(message);

  result = messageBlock.eskPackets[0].decryptSessionKey(
      privateKeyBlock.packets[3].cipher.getKey());
  messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                            messageBlock.eskPackets[0].getSessionKey());
  var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
      messageBlock.encryptedData.data);
  decrypted_packet.decompress();
  var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
  assertEquals(e2e.byteArrayToString(decompressed_packet.data),
               'hello world new\n');
}

/**
 * Tests decryption with message and keys generated by gpg.
 * Uses RSA, iterated S2K, BLOWFISH, MD5, and ZIP.
 */
function testDecryptionZIPMD5BLOWFISH() {
  var key =
    '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    '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\n' +
    '1KwNtVw=\n' +
    '=wHzz\n' +
    '-----END PGP PRIVATE KEY BLOCK-----';
  var privateKeyBlock = e2e.openpgp.block.factory.parseAscii(key);

  var passphrase = e2e.stringToByteArray('test');
  // Main key doesn't have what we want, but decrypt it anyways:
  privateKeyBlock.keyPacket.cipher.unlockKey(passphrase);
  privateKeyBlock.packets[3].cipher.unlockKey(passphrase);
  var message =
    '-----BEGIN PGP MESSAGE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'hIsDXrdcIWJXR5IBA/ipiFZkZQYSsIN9kjPtUqofmKotkQq/Y+f0PVkyyZx24EIr\n' +
    'Hw7OHbU0M3q/T4Pq61MPVWd6ksSg27PS+RKWaeIoX1DvJ08hSjH8LNDtgQTtxkO1\n' +
    'TQw5BHTDHWXu4QEMEtfiQzAdiJ9H1u4F3+reEViK3nMTogyOjxVlGVvnHVhD0kIB\n' +
    'ycThMOkHp6gNXIF454+PuzElA734g58vOndl0MyCAUk0zao4DsP7NHEQa3jSOGfA\n' +
    'Ut1PTQ+9aD4qb5XuxEbSJ2A=\n' +
    '=pzUF\n' +
    '-----END PGP MESSAGE-----';
  var messageBlock = e2e.openpgp.block.factory.parseAscii(message);

  result = messageBlock.eskPackets[0].decryptSessionKey(
      privateKeyBlock.packets[3].cipher.getKey());
  messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                            messageBlock.eskPackets[0].getSessionKey());
  var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
      messageBlock.encryptedData.data);
  decrypted_packet.decompress();
  var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
  assertEquals(e2e.byteArrayToString(decompressed_packet.data),
               'hello world new\n');
}

/**
 * Tests decryption with a simple message and key made by evn@google.com.
 * Uses CAST5.
 */
function testDecryptionSimple() {
  var message =
    '-----BEGIN PGP MESSAGE-----\n' +
    'Version: haneWIN JavascriptPG v2.0\n' +
    '\n' +
    'hIwDPgpnp2BW/IEBA/9x4WCm9OKX8Y43KMEOXuy0zuoBzUIjSUk7P7AnnZQV\n' +
    'OjD14sg8Yk4shnOoBjxwXe8kyqQZLzoLR6NUBQk47vteMVkZx72HXJf5npqE\n' +
    'eE1/GkpKUaWhBd4bYTK/Ed8uMWc85pC0lu9WNmn/F3Qie2P73tVNBKeXCUIo\n' +
    '2akUkBhdyKQtsqszOGyONIC8pNhGo3eohEtTNVwqzjmLDeEKmJg6yJqNiUAx\n' +
    'dKvwjg6CY3l2\n' +
    '=SoLd\n' +
    '-----END PGP MESSAGE-----';
  var messageBlock = e2e.openpgp.block.factory.parseAscii(message);

  var key =
    '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
    'Version: BCPG C# v1.6.1.0\n' +
    '\n' +
    'lQHsBE6R408BBADSSbEiJ21/y+7uKqxWi1aT4YzNaZjV2roZEoQdSEqtnWJpE7sW\n' +
    'ESKx6KqkvFCApKl2tHVkLwjjyJA4HbzWZpH2vREfFVeL4r0OFykvmbLUoEOKJLNT\n' +
    'QMNd3/PWSGcW5CX6WKeYCQ0jqNDBRKtmvGdLWY3gi9UI55K4+HCLdj2m5wARAQAB\n' +
    '/wMDAiLRJsUTRAvpYL/usCC7NiH2lmhjrUuNyfGDaAA/uXEPSj918tZsHFxGomHJ\n' +
    '3jU8TGaWEtpkh3Z0V9nziv08XrJuZ8eE3T5gD/DiwCgskhNShuq94bsio7REW/Ic\n' +
    'fv6FMjU/dTprByVbZAlU+mQTsQAaYk/4CHqFPCYprgIEFoVij0iOzvYeM4/kWHsA\n' +
    'HO0PMoop/TbxlgiV1NYbVGYjzGkR6JAxgAutjyE03ydif7uLCwWa0FOAHRt71LJ5\n' +
    'oRjigVxVh/k+6XLsl5nYhhomxA5yA8FnKEY1pzhtAuxnc4GFad+LqrZzTwMBe/u9\n' +
    'IzNlSvP7U2YfRXmiEUX9d0jIblJu8yoej6Y/BMbf2KAKekgN8hKrcygwL1mhVZ+3\n' +
    'YaQCx6GeN/52VXtn2bJQ7l6AAjMQlEaAcEc1opY+Yfa/4Fu3IujkuJ6I7TRxFMWy\n' +
    'jONu8vkfaaUrbCZurE6BtBF0ZXN0QHRlc3QuZXhhbXBsZYicBBABAgAGBQJOkeNP\n' +
    'AAoJED4KZ6dgVvyB1mID/R/lVuN+zeTGcj3bjn6Ep0QWJGdmw8AMFQ3xx65rmpQL\n' +
    'Rq1NsRCz/syj4aRCPni/rwrUe0pWF6zAqJz97LpB/07ei6Hadjbz9nGqxOjo/n8U\n' +
    'ixPKLMzKqY1JCKM6r5YZabd3xXVpQt0PfBuaFLtBeH6K7LfgYYkqgZwZGJNQlhVW\n' +
    '=D1+C\n' +
    '-----END PGP PRIVATE KEY BLOCK-----';
  var privateKeyBlock = e2e.openpgp.block.factory.parseAscii(key);

  var passphrase = e2e.stringToByteArray('test');
  privateKeyBlock.keyPacket.cipher.unlockKey(passphrase);
  result = messageBlock.eskPackets[0].decryptSessionKey(
      privateKeyBlock.keyPacket.cipher.getKey());
  messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                            messageBlock.eskPackets[0].getSessionKey());
  var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
      messageBlock.encryptedData.data);
  assertEquals(e2e.byteArrayToString(decrypted_packet.data),
               'hello, world.\r\n');
}

/**
 * Encrypts a message and then decrypts it.
 */
function testEncryption() {
  var plaintext = 'hello world from encrypted message';
  var plaintextFilename = 'file.txt';
  var publicKeyAscii =
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'mI0EUcy6DgEEAJb0T7gQlfKQWmR0dLUrueRMVy8UemcmxsdIH30/HqJvqO6xU0lK\n' +
    'NaFtaVxBdenAMpEooi1EcTi/bOKfz36FY/FARTiXv1LXuLzFJdPyjTYjh7tw+uOP\n' +
    'UlLJCTZikgrnM07txTUiVVEetOa+unyKn17EX0PlSpAbGZedyO0nGwXzABEBAAG0\n' +
    'BnRlc3QgNIi4BBMBAgAiBQJRzLoOAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX\n' +
    'gAAKCRAG/5ysCS2oCL2SA/9EV9j3T/TM3VRD0NvNySHodcxCP1BF0zm/M84I/WHQ\n' +
    'sGKmHStfCqqEGruB8E6NHQMJwNp1TzcswuxE0wiTJiXKe3w3+GZhPHdW5zcgiMKK\n' +
    'YLn80Tk6fUMx1zVZtXlSBYCN5Op/axjQRyb+fGnXOhmboqQodYaWS7qhJWQJilH6\n' +
    'iriNBFHMug4BBADDTMshHtyYhLmWC7793FlOFl5tkcEfdFKJRm30k/9yky4cuz//\n' +
    'Xe4uXM72SaTI1Dfi6UIz5ZuFTxw3bnAXav+SV4Q4dZo0hb4jU8YaQfDL4TsRp7uO\n' +
    '6iqxd8nlsh9JnBKE6Fk/CW5FoMZZ3/yEm3pq924Uv2AZlO6dafgXecyqNQARAQAB\n' +
    'iJ8EGAECAAkFAlHMug4CGwwACgkQBv+crAktqAhENwQAkMY/nds36KgzwfMPpxtB\n' +
    'aq8GbrUqY1r8lBl6a/bi8qeOuEgQmIxM2OpVPtL04c1c1hLflPCi1SQUlCIh3DkE\n' +
    'GQIcy0/wxUZdCvZK0mF5nZSq6tez3CwqbeOA4nBOLwbxho50VqxBpR4qypYrB2ip\n' +
    'ykxlwiqudEe0sE2b1KwNtVw=\n' +
    '=nHBL\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  var publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);

  var literal = new e2e.openpgp.packet.LiteralData(
      e2e.openpgp.packet.LiteralData.Format.TEXT,
      e2e.stringToByteArray(plaintextFilename),
      1375136046,
      e2e.stringToByteArray(plaintext)
      );
  asyncTestCase.waitForAsync('Waiting for encryption.');
  e2e.openpgp.block.EncryptedMessage.construct(
      literal,
      [publicKeyBlock.subKeys[0]]).addCallback(function(block) {
    var ascii = e2e.openpgp.asciiArmor.encode(block.header,
                                                  block.serialize());

    // Decrypt the message.
    var messageBlock = e2e.openpgp.block.factory.parseAscii(ascii);

    var privateKeyAscii =
      '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
      'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
      '\n' +
      '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\n' +
      '1KwNtVw=\n' +
      '=wHzz\n' +
      '-----END PGP PRIVATE KEY BLOCK-----';
    var privateKeyBlock = e2e.openpgp.block.factory.parseAscii(privateKeyAscii);

    var passphrase = e2e.stringToByteArray('test');
    // Main key doesn't have what we want, but decrypt it anyways:
    privateKeyBlock.keyPacket.cipher.unlockKey(passphrase);
    privateKeyBlock.packets[3].cipher.unlockKey(passphrase);
    asyncTestCase.waitForAsync('Waiting for session key decryption.');
    result = messageBlock.eskPackets[0].decryptSessionKey(
        privateKeyBlock.packets[3].cipher.getKey());
    result.addCallback(function() {
      asyncTestCase.continueTesting();
      messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                          messageBlock.eskPackets[0].getSessionKey());
      var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
          messageBlock.encryptedData.data);
      decrypted_packet.decompress();
      var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
      assertEquals(plaintext,
                   e2e.byteArrayToString(decompressed_packet.data));
      assertEquals(plaintextFilename,
                   e2e.byteArrayToString(decompressed_packet.filename));
    }).addErrback(function(e) {
      fail(e);
    });
  }).addErrback(function(e) {
    fail(e);
  });
}


/**
 * Tests symmetric decryption with message generated by gpg.  Uses 3DES.
 * Has no encrypted session key, so it uses S2K(passphrase) for the session key.
 */
function testSymmetricDecryption() {
  var passphrase = e2e.stringToByteArray('test');
  var message =
    '-----BEGIN PGP MESSAGE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'jA0EAgMCeHIy+QZ7cc1gySvSmaAcX051wS8oEH6YPv4xJVV1KheIb63lAwINN8nC\n' +
    'p02jLjxl6M+ptJcl\n' +
    '=P0gK\n' +
    '-----END PGP MESSAGE-----';
  var messageBlock = e2e.openpgp.block.factory.parseAscii(message);
  asyncTestCase.waitForAsync('Waiting for decryption.');
  messageBlock.eskPackets[0]
    .decryptSessionKey(
      {'passphrase': passphrase})
    .addCallback(function() {
      asyncTestCase.continueTesting();
      messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                          messageBlock.eskPackets[0].getSessionKey());
      var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
          messageBlock.encryptedData.data);
      decrypted_packet.decompress();
      var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
      assertEquals(e2e.byteArrayToString(decompressed_packet.data),
                   'hello world new\n');
    }).addErrback(function(e) {
      fail(e);
    });
}


/**
 * Tests symmetric decryption with message generated by gpg.  Uses CAST5.
 * This has an encrypted session key and an extra PK ESK.
 */
function testSymmetricESKDecryption() {
  var passphrase = e2e.stringToByteArray('test');
  var message =
    '-----BEGIN PGP MESSAGE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'hIwDXrdcIWJXR5IBBACvfmXw3FIj80OzUZ9v9XepskeH5cuBEBK4L1eGP50/St7r\n' +
    '+3rSXZrYRP/fi/SvopMisc82YXrfIL7N/3EM8BMBxcssJK1u6fEcOkxosE978NGs\n' +
    'fOQpRV4LdgtYAmFqVQqWscj/LQMq09slYZPATG7vVg83G0gN4vsjOVlWcOBwSowm\n' +
    'BAMDAisQHqM4pS+1YPnuMMN/GbVddNGpPwhP62E6dFmrfgzuKp7SSAHBxxrqwJAb\n' +
    'h2MHV2/xV55z+qcfrXuW9xCepTd1z3jVGmfq/br31h3xwp6jZWjQsvshZ2P6Pt89\n' +
    '9BWnfhsQBXxMhgUsSJJfuA==\n' +
    '=Z581\n' +
    '-----END PGP MESSAGE-----';
  var messageBlock = e2e.openpgp.block.factory.parseAscii(message);

  result = messageBlock.eskPackets[1].decryptSessionKey(
    {'passphrase': passphrase});
  messageBlock.encryptedData.decrypt(messageBlock.eskPackets[1].symmetricAlgorithm,
                                      messageBlock.eskPackets[1].getSessionKey());
  var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
      messageBlock.encryptedData.data);
  decrypted_packet.decompress();
  var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
  assertEquals(e2e.byteArrayToString(decompressed_packet.data),
               'hello world new\n');
}


/**
 * Tests symmetric encryption with message generated by gpg.
 * This has an encrypted session key and an extra PK ESK.
 */
function testSymmetricEncryption() {
  var passphrase = e2e.stringToByteArray('test');
  var plaintext = 'hello world from encrypted message';
  var plaintextFilename = 'file.txt';

  var literal = new e2e.openpgp.packet.LiteralData(
      e2e.openpgp.packet.LiteralData.Format.TEXT,
      e2e.stringToByteArray(plaintextFilename),
      1375136046,
      e2e.stringToByteArray(plaintext)
      );
  asyncTestCase.waitForAsync('Waiting for encryption.');
  e2e.openpgp.block.EncryptedMessage.construct(
      literal,
      [],  // No public keys to encrypt to.
      [passphrase]// Passphrases for symmetric-key ESKs.
  ).addCallback(function(block){
    var message = e2e.openpgp.asciiArmor.encode(block.header,
                                                    block.serialize());

    // Decrypt the message.
    var messageBlock = e2e.openpgp.block.factory.parseAscii(message);

    var result = messageBlock.eskPackets[0].decryptSessionKey(
      {'passphrase': passphrase});
    asyncTestCase.waitForAsync('Waiting for decryption.');
    result.addCallback(function() {
      asyncTestCase.continueTesting();
      messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                          messageBlock.eskPackets[0].getSessionKey());
      var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
          messageBlock.encryptedData.data);
      decrypted_packet.decompress();
      var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
      assertEquals(plaintext,
                   e2e.byteArrayToString(decompressed_packet.data));
      assertEquals(plaintextFilename,
                   e2e.byteArrayToString(decompressed_packet.filename));
    }).addErrback(function(e) {
      fail(e);
    });
  }).addErrback(function(e) {
      fail(e);
  });
}


function testDecryptionECDH() {
  // SecretKey packet is ECDSA with CAST5. SecretSubkey is ECDH.
  var privateKeyAscii =
    '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
    'Version: GnuPG v2.1.0-ecc (GNU/Linux)\n' +
    '\n' +
    'lJ0EUh5AoBMIKoZIzj0DAQcCAwT68182duSEJFXKa+qkBa0Vgeswnv8GP8tKYiU/\n' +
    'MCZd6dGTvrtf2gSjyAsVkB0V0idW7i8yW1wfh3y2AbGWDr/d/gMDAt9ake5OhVV2\n' +
    'vphqDL6ay87d7ikCevFkhfACXb6HRHaVim7DU44JVscpFIOUE2lcgTJP5Ygeko/r\n' +
    'UY5P1g3S3gEFyj1E9MYOtB9lY2MgcmVhbCBuYW1lIDxlY2NAZXhhbXBsZS5jb20+\n' +
    'iHoEExMIACIFAlIeQKACGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOrr\n' +
    'inav6MhnxtcA/iAteDFo/P5SU5XV/8/4BN9xf28SuvwFipnjjyOmvB0eAP4kPM5L\n' +
    'Ap2EW+QIyG6+CJP1No9uWyZTdLPkTRgLtYhiGJyhBFIeQKASCCqGSM49AwEHAgME\n' +
    'gk1dVpgPCM38NBNoBcvehm7mt6aUmK8mDb/MSHo2/NlwfTh+BDCoVX5asSetzuW2\n' +
    'RbnP6sCBwfsuLSrSWUVauwMBCAf+AwMC31qR7k6FVXa+IvSLivg+6zKHEJ/Wa0Az\n' +
    'rh02A4SC/mMjAg2VfgxFFKJv9Jph2i1Gwp0xguQ2aWKM3ecwE79i3QyV4UpcRh6I\n' +
    'YQQYEwgACQUCUh5AoAIbDAAKCRDq64p2r+jIZzqQAP9dEqUKkRjGkEWHFYXl2oQi\n' +
    'n/ECJvEyoOB0gEMGwqIlWQEA3xJzLg7nerNCcvJerLbQaagVWu8iXKknMwAKy9uN\n' +
    '0No=\n' +
    '=BeRO\n' +
    '-----END PGP PRIVATE KEY BLOCK-----';
  var privateKeyBlock = e2e.openpgp.block.factory.parseAscii(privateKeyAscii);
  var passphrase = e2e.stringToByteArray('test');
  privateKeyBlock.keyPacket.cipher.unlockKey(passphrase);  // ECDSA
  privateKeyBlock.subKeys[0].cipher.unlockKey(passphrase);  // ECDH

  var message =
    '-----BEGIN PGP MESSAGE-----\n' +
    'Version: GnuPG v2.1.0-ecc (GNU/Linux)\n' +
    '\n' +
    'hH4D26lbUsH7upcSAgMEer7d403f0YiuBfESYnfopwbwGh0FydGiFUWk8anmrzwu\n' +
    'nq94mFqYpvu8z0ZHI9krdjygDoch7lKKTjDdpIUMNzClxfIZ00UMBmEP/aiYYA0r\n' +
    'y+gg8dCIlSjoyyDgMRmjaCG+dZISgwGT5iCnV1zA9tjSUAFuzk6Dd2e9vEN0zRdy\n' +
    'vuFchOJzHuZXeF0lcCPufuHSnsTAMuU3J6q7W9PMyvailbTq1MpSm7r8QMCpa/bX\n' +
    'rT0WWBsy5HbaxkFqF5G/Bkbz\n' +
    '=Mkhm\n' +
    '-----END PGP MESSAGE-----';
  var messageBlock = e2e.openpgp.block.factory.parseAscii(message);
  var result = messageBlock.eskPackets[0].decryptSessionKey(    // Use ECDH private key to decrypt
      privateKeyBlock.subKeys[0].cipher.getKey());  // symmetric session key.
  asyncTestCase.waitForAsync('Waiting for decryption.');
  result.addCallback(function() {
    asyncTestCase.continueTesting();
    messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                        messageBlock.eskPackets[0].getSessionKey());
    var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
        messageBlock.encryptedData.data);
    decrypted_packet.decompress();
    var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
    assertEquals(e2e.byteArrayToString(decompressed_packet.data),
                 'hello world new\n');
  }).addErrback(function(e) {
      fail(e);
  });
}


function testEncryptionECDH() {
  var plaintext = 'hello world from encrypted message';
  var plaintextFilename = 'file.txt';
  var publicKeyAscii =
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v2.1.0-ecc (GNU/Linux)\n' +
    '\n' +
    'mFIEUh5AoBMIKoZIzj0DAQcCAwT68182duSEJFXKa+qkBa0Vgeswnv8GP8tKYiU/\n' +
    'MCZd6dGTvrtf2gSjyAsVkB0V0idW7i8yW1wfh3y2AbGWDr/dtB9lY2MgcmVhbCBu\n' +
    'YW1lIDxlY2NAZXhhbXBsZS5jb20+iHoEExMIACIFAlIeQKACGwMGCwkIBwMCBhUI\n' +
    'AgkKCwQWAgMBAh4BAheAAAoJEOrrinav6MhnxtcA/iAteDFo/P5SU5XV/8/4BN9x\n' +
    'f28SuvwFipnjjyOmvB0eAP4kPM5LAp2EW+QIyG6+CJP1No9uWyZTdLPkTRgLtYhi\n' +
    'GLhWBFIeQKASCCqGSM49AwEHAgMEgk1dVpgPCM38NBNoBcvehm7mt6aUmK8mDb/M\n' +
    'SHo2/NlwfTh+BDCoVX5asSetzuW2RbnP6sCBwfsuLSrSWUVauwMBCAeIYQQYEwgA\n' +
    'CQUCUh5AoAIbDAAKCRDq64p2r+jIZzqQAQCcv0VOQFiNOM6JNdLHTqlCYxeoz09d\n' +
    'UP3LdgcnLED/YwD9FqcNrkok9BuXJ9+rXTSu+uqdWB7gpMO9mfk65d5IQ+s=\n' +
    '=xRCj\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  var publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);

  var literal = new e2e.openpgp.packet.LiteralData(
      e2e.openpgp.packet.LiteralData.Format.TEXT,
      e2e.stringToByteArray(plaintextFilename),
      1375136046,
      e2e.stringToByteArray(plaintext));
  asyncTestCase.waitForAsync('Waiting for encryption.');
  e2e.openpgp.block.EncryptedMessage.construct(
      literal,
      [publicKeyBlock.subKeys[0]]).addCallback(function(block) {
    var ascii = e2e.openpgp.asciiArmor.encode(block.header,
                                                  block.serialize());

    var privateKeyAscii =
      '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
      'Version: GnuPG v2.1.0-ecc (GNU/Linux)\n' +
      '\n' +
      'lJ0EUh5AoBMIKoZIzj0DAQcCAwT68182duSEJFXKa+qkBa0Vgeswnv8GP8tKYiU/\n' +
      'MCZd6dGTvrtf2gSjyAsVkB0V0idW7i8yW1wfh3y2AbGWDr/d/gMDAt9ake5OhVV2\n' +
      'vphqDL6ay87d7ikCevFkhfACXb6HRHaVim7DU44JVscpFIOUE2lcgTJP5Ygeko/r\n' +
      'UY5P1g3S3gEFyj1E9MYOtB9lY2MgcmVhbCBuYW1lIDxlY2NAZXhhbXBsZS5jb20+\n' +
      'iHoEExMIACIFAlIeQKACGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOrr\n' +
      'inav6MhnxtcA/iAteDFo/P5SU5XV/8/4BN9xf28SuvwFipnjjyOmvB0eAP4kPM5L\n' +
      'Ap2EW+QIyG6+CJP1No9uWyZTdLPkTRgLtYhiGJyhBFIeQKASCCqGSM49AwEHAgME\n' +
      'gk1dVpgPCM38NBNoBcvehm7mt6aUmK8mDb/MSHo2/NlwfTh+BDCoVX5asSetzuW2\n' +
      'RbnP6sCBwfsuLSrSWUVauwMBCAf+AwMC31qR7k6FVXa+IvSLivg+6zKHEJ/Wa0Az\n' +
      'rh02A4SC/mMjAg2VfgxFFKJv9Jph2i1Gwp0xguQ2aWKM3ecwE79i3QyV4UpcRh6I\n' +
      'YQQYEwgACQUCUh5AoAIbDAAKCRDq64p2r+jIZzqQAP9dEqUKkRjGkEWHFYXl2oQi\n' +
      'n/ECJvEyoOB0gEMGwqIlWQEA3xJzLg7nerNCcvJerLbQaagVWu8iXKknMwAKy9uN\n' +
      '0No=\n' +
      '=BeRO\n' +
      '-----END PGP PRIVATE KEY BLOCK-----';
    var privateKeyBlock = e2e.openpgp.block.factory.parseAscii(privateKeyAscii);
    var passphrase = e2e.stringToByteArray('test');
    privateKeyBlock.keyPacket.cipher.unlockKey(passphrase);
    privateKeyBlock.subKeys[0].cipher.unlockKey(passphrase);

    // Decrypt the message.
    var messageBlock = e2e.openpgp.block.factory.parseAscii(ascii);
    asyncTestCase.waitForAsync('Waiting for encryption.');
    messageBlock.eskPackets[0]
      .decryptSessionKey(privateKeyBlock.subKeys[0].cipher.getKey())
      .addCallback(function(success) {
        asyncTestCase.continueTesting();
        assert('Session key decryption should succeded.', success);
        messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                            messageBlock.eskPackets[0].getSessionKey());
        var decrypted_packet = e2e.openpgp.parse.parseSerializedPacket(
            messageBlock.encryptedData.data);
        decrypted_packet.decompress();
        var decompressed_packet = e2e.openpgp.parse.parseSerializedPacket(decrypted_packet.data);
        assertEquals(plaintext,
                     e2e.byteArrayToString(decompressed_packet.data));
        assertEquals(plaintextFilename,
                     e2e.byteArrayToString(decompressed_packet.filename));
      })
      .addErrback(function(e) {
        fail(e);
      });
    })
    .addErrback(function(e) {
      fail(e);
    });
}


function testPublickeyImport() {
  // Public key has DSA signatures.
  var publicKeyAscii =
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: PGPfreeware 6.5.8 for non-commercial use <http://www.pgp.com>\n' +
    '\n' +
    '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\n' +
    'TqjmnXbR7ZWHvyF8lI4=\n' +
    '=bI+z\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  var publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);

}

function testClearSignRSA() {
  var publicKeyAscii =
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'mI0EUcy6DgEEAJb0T7gQlfKQWmR0dLUrueRMVy8UemcmxsdIH30/HqJvqO6xU0lK\n' +
    'NaFtaVxBdenAMpEooi1EcTi/bOKfz36FY/FARTiXv1LXuLzFJdPyjTYjh7tw+uOP\n' +
    'UlLJCTZikgrnM07txTUiVVEetOa+unyKn17EX0PlSpAbGZedyO0nGwXzABEBAAG0\n' +
    'BnRlc3QgNIi4BBMBAgAiBQJRzLoOAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX\n' +
    'gAAKCRAG/5ysCS2oCL2SA/9EV9j3T/TM3VRD0NvNySHodcxCP1BF0zm/M84I/WHQ\n' +
    'sGKmHStfCqqEGruB8E6NHQMJwNp1TzcswuxE0wiTJiXKe3w3+GZhPHdW5zcgiMKK\n' +
    'YLn80Tk6fUMx1zVZtXlSBYCN5Op/axjQRyb+fGnXOhmboqQodYaWS7qhJWQJilH6\n' +
    'iriNBFHMug4BBADDTMshHtyYhLmWC7793FlOFl5tkcEfdFKJRm30k/9yky4cuz//\n' +
    'Xe4uXM72SaTI1Dfi6UIz5ZuFTxw3bnAXav+SV4Q4dZo0hb4jU8YaQfDL4TsRp7uO\n' +
    '6iqxd8nlsh9JnBKE6Fk/CW5FoMZZ3/yEm3pq924Uv2AZlO6dafgXecyqNQARAQAB\n' +
    'iJ8EGAECAAkFAlHMug4CGwwACgkQBv+crAktqAhENwQAkMY/nds36KgzwfMPpxtB\n' +
    'aq8GbrUqY1r8lBl6a/bi8qeOuEgQmIxM2OpVPtL04c1c1hLflPCi1SQUlCIh3DkE\n' +
    'GQIcy0/wxUZdCvZK0mF5nZSq6tez3CwqbeOA4nBOLwbxho50VqxBpR4qypYrB2ip\n' +
    'ykxlwiqudEe0sE2b1KwNtVw=\n' +
    '=nHBL\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  var publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);

  // Signed by user: "test 4" 1024-bit RSA key, ID 092DA808, 06 ff ...
  var clearSign =
    '-----BEGIN PGP SIGNED MESSAGE-----\n' +
    'Hash: SHA1\n' +
    '\n' +
    'hello world new\n' +
    '-----BEGIN PGP SIGNATURE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'iJwEAQECAAYFAlIny1sACgkQBv+crAktqAgPqgP/bG1lJAyVBa99rJTLn9RAJsC0\n' +
    '2d7hJBdEiwmakEzbGfWG48RM7mq4X+W3j36D8qeCWpYkJk+zd4g25TJ7DIwoBfCv\n' +
    'J8S0vVfQ6FYTNHLuAggXs7ooLfovq2fP6iuVjwNX57JDxllHmS8tPAbIgIs+VRag\n' +
    'hOia0yJgN0DoFSylakY=\n' +
    '=qRFP\n' +
    '-----END PGP SIGNATURE-----';
  var parsed = e2e.openpgp.asciiArmor.parseClearSign(clearSign);
  var signaturePacket = e2e.openpgp.parse.parseSerializedPacket(parsed.signature);
  assertTrue(signaturePacket.verify(e2e.stringToByteArray(parsed.body),
                                    publicKeyBlock.keyPacket.cipher));
  assertFalse(signaturePacket.verify(e2e.stringToByteArray('bad world new'),
                                     publicKeyBlock.keyPacket.cipher));
}

function testClearSignInvalidHashAlgo() {
  var publicKeyAscii =
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'mI0EUcy6DgEEAJb0T7gQlfKQWmR0dLUrueRMVy8UemcmxsdIH30/HqJvqO6xU0lK\n' +
    'NaFtaVxBdenAMpEooi1EcTi/bOKfz36FY/FARTiXv1LXuLzFJdPyjTYjh7tw+uOP\n' +
    'UlLJCTZikgrnM07txTUiVVEetOa+unyKn17EX0PlSpAbGZedyO0nGwXzABEBAAG0\n' +
    'BnRlc3QgNIi4BBMBAgAiBQJRzLoOAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX\n' +
    'gAAKCRAG/5ysCS2oCL2SA/9EV9j3T/TM3VRD0NvNySHodcxCP1BF0zm/M84I/WHQ\n' +
    'sGKmHStfCqqEGruB8E6NHQMJwNp1TzcswuxE0wiTJiXKe3w3+GZhPHdW5zcgiMKK\n' +
    'YLn80Tk6fUMx1zVZtXlSBYCN5Op/axjQRyb+fGnXOhmboqQodYaWS7qhJWQJilH6\n' +
    'iriNBFHMug4BBADDTMshHtyYhLmWC7793FlOFl5tkcEfdFKJRm30k/9yky4cuz//\n' +
    'Xe4uXM72SaTI1Dfi6UIz5ZuFTxw3bnAXav+SV4Q4dZo0hb4jU8YaQfDL4TsRp7uO\n' +
    '6iqxd8nlsh9JnBKE6Fk/CW5FoMZZ3/yEm3pq924Uv2AZlO6dafgXecyqNQARAQAB\n' +
    'iJ8EGAECAAkFAlHMug4CGwwACgkQBv+crAktqAhENwQAkMY/nds36KgzwfMPpxtB\n' +
    'aq8GbrUqY1r8lBl6a/bi8qeOuEgQmIxM2OpVPtL04c1c1hLflPCi1SQUlCIh3DkE\n' +
    'GQIcy0/wxUZdCvZK0mF5nZSq6tez3CwqbeOA4nBOLwbxho50VqxBpR4qypYrB2ip\n' +
    'ykxlwiqudEe0sE2b1KwNtVw=\n' +
    '=nHBL\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  var publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);

  // Signed by user: "test 4" 1024-bit RSA key, ID 092DA808, 06 ff ...
  var clearSign =
    '-----BEGIN PGP SIGNED MESSAGE-----\n' +
    'Hash: SHA1\u003btampered hash.\n' +
    '\n' +
    'hello world new\n' +
    '-----BEGIN PGP SIGNATURE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'iJwEAQECAAYFAlIny1sACgkQBv+crAktqAgPqgP/bG1lJAyVBa99rJTLn9RAJsC0\n' +
    '2d7hJBdEiwmakEzbGfWG48RM7mq4X+W3j36D8qeCWpYkJk+zd4g25TJ7DIwoBfCv\n' +
    'J8S0vVfQ6FYTNHLuAggXs7ooLfovq2fP6iuVjwNX57JDxllHmS8tPAbIgIs+VRag\n' +
    'hOia0yJgN0DoFSylakY=\n' +
    '=qRFP\n' +
    '-----END PGP SIGNATURE-----';
  var parsed = e2e.openpgp.asciiArmor.parseClearSign(clearSign);
  var signaturePacket = e2e.openpgp.parse.parseSerializedPacket(parsed.signature);
  assertFalse(signaturePacket.verify(e2e.stringToByteArray(parsed.body),
    publicKeyBlock.keyPacket.cipher, parsed.hash));
  assertTrue(signaturePacket.verify(e2e.stringToByteArray(parsed.body),
    publicKeyBlock.keyPacket.cipher, 'SHA1'));
}

function testClearSignDSA() {
  var publicKeyAscii =  // 1024bit DSA key
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'mQGiBFJ8FxURBADDow5amQ608iHV6P8azF1Y75R61c1A0EDqVVFYB+ZUOi3/8QJC\n' +
    'EthxPLwXlXzWQBef9UToB6vvCjqIzChRTQu5sHK+KJyiFSuDZvkvF29tYS2cmJam\n' +
    'wMfHbF6NwKFt+mmV5BhnkIqYtoM+7/L9wxpKZv6k1xee4YHXFwI8w6mcawCgsCeP\n' +
    '+KMc57Wh6xTWZgPSaj/kAH8EAI7J8ElD/uU4lYR7HzCEAYU4r7QCleRoVxCRubPl\n' +
    '4OnLVPZ0dsb7pXR86SV6nQpZME8YL2bCl01GR8X+s8zF+o0b3AxfarrArIUm4n5n\n' +
    'q7OcopqgfQzEq2o4UnFENnJH/Z20+AyqogPE2ehJ9I2TN7CjKz0qb8RqLZDwJOJS\n' +
    'vmklA/9UnQYZFLPNzgBd0J8fp/1oB+D8DsFfUBLd/odC+T1vGJe6OBGdcNtPq3jH\n' +
    'rPeJj6XoIPKsHNP0Fw9VwyQms5ASJaiZozaPoJr4HOVLD/0XhbKjDRGotdFqOoAr\n' +
    'AcXx25OnyvZOIINiYpaZe8ryiApG63WDQWg3yJsmRFzgz4dtbLQQZHNhIHNpZ25p\n' +
    'bmcgdXNlcohiBBMRAgAiBQJSfBcVAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX\n' +
    'gAAKCRB/gSewOu/OcVqrAJwLBpA7+Z0EpTx5l96DI5GeDEzKLgCgqyqa64yORpSB\n' +
    'yTUJDRMapABTQcA=\n' +
    '=gg4f\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  var publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);

  var clearSign =
    '-----BEGIN PGP SIGNED MESSAGE-----\n' +
    'Hash: SHA1\n' +
    '\n' +
    'hello world dsa\n' +
    '-----BEGIN PGP SIGNATURE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'iEYEARECAAYFAlJ8HZkACgkQf4EnsDrvznG4wQCfd5A7goCRHjpqWXRglezKLjJE\n' +
    'MRkAn2NRjuxPA0sHfNuEFZd2Yv02TE6C\n' +
    '=ov4Z\n' +
    '-----END PGP SIGNATURE-----';
  var parsed = e2e.openpgp.asciiArmor.parseClearSign(clearSign);
  var signaturePacket = e2e.openpgp.parse.parseSerializedPacket(parsed.signature);
  assertTrue(signaturePacket.verify(e2e.stringToByteArray(parsed.body),
                                    publicKeyBlock.keyPacket.cipher,
                                    parsed.hash));
  assertFalse(signaturePacket.verify(e2e.stringToByteArray(parsed.body),
                                     publicKeyBlock.keyPacket.cipher, 'OTHER'));
  assertFalse(signaturePacket.verify(e2e.stringToByteArray('bad world new'),
                                     publicKeyBlock.keyPacket.cipher));

  publicKeyAscii =  // 2048bit DSA key
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'mQMuBFJ8K1oRCACv4QL0+GnScNvFhZB1sMrRxibowhwv1UAAxz/nygIaTWcj0cvV\n' +
    'IA2d4/5cyuNC2LDb193Id9ODR6J8nG7GuZpTOCXPMx05VV5LzNfVMiVe+8Sx6nh+\n' +
    'O6C0Am9o23wZHFMDUqX/c++9WC+DxkyBkeH0gbeE/aWb0eIGyxbw3YmiYvg7km+T\n' +
    'gUyN5bpSpcEFsaWzL9+PayI13P4ZGRKqwhoR00HJ/oiFep4v1iTnlf/PdzKW2wTQ\n' +
    '3nwOHKsbsrP7MN1CYBfuHOfOstWmbyAkROACbzoFOhXoRtHJjR0Kng+Hhbroawzu\n' +
    'fgMCxmgHYKN4krtKyiTQ56JG9ORUuoFm+AUfAQCFTiit5Q8M2ChfnmGPVD/g+1BC\n' +
    '8QdAT5KAe5Qkf9KcsQgApWF3Aa8Y/MAycSyjS06+cXxP/KqGuP2gpZfpFbVPk3z1\n' +
    'Ams3YzJuT4OUGMia1qp8xilch2nnZS3TJmIelHTthmjY5iw/eFN52JvPXXHJJgyb\n' +
    '3Q9d1l08J9BYwDnXKqM45lW4EY2Iswox91STj1r3GFWWgPpUrLGpdd/FDNAVL6EU\n' +
    'G6PWn2/g/sGAAueqPpbpmgiFXZrF3pXnm6H/LlHNlbqBvhI7kk5Wj9NHm6hJHzdq\n' +
    'm5IgoQDOfgMeOjE/jbJnXLjZiYh4eKQ0ruCOL37sYLmQvd1tC8Pc6Ld2MNW/66Wk\n' +
    'ph40mUNig9cjZ1GBtf2Ql6aTfOCr98gy6B6S9U/RNgf/UBBkh1FVB/TayNroyUxA\n' +
    'a+xUodRgaLNTfs/VVrYjxqUXlwxfPDtH0fRGELfAukXD1MLqeXSNjoMc2he2xJ5a\n' +
    'oqpuOFLWqbP6U6MdcUlIeS4sPsjpq4/z1O0ZL5YtRFwTVgpC+1tjVFSNmS7wtpt8\n' +
    'stpuH34qZ8Is1V60hPGNrocKsiRHEsLyDzGoHoSmHS8z/SZ+Hg4vJiWCBnC3ao9l\n' +
    'niyzXxhOx94oiyfxOEfePH3QpTtQbXs5J+hpS+2e29AQGONUTA/JgZ5FNapfZN9T\n' +
    'dDWPTDOKM7p3vL3X7tXdOCnf5pdxO1OwMbp9IIFxuZBSJXYTEQ7d7s9wFj3HZ0p6\n' +
    'yLQIZHNhIDIwNDiIegQTEQgAIgUCUnwrWgIbAwYLCQgHAwIGFQgCCQoLBBYCAwEC\n' +
    'HgECF4AACgkQcvZy0yMm+1KkmwD/XSHbZfWqSyUIe6Q/yDSYA8gZUKtoL+eX+DMH\n' +
    '6INFXCwA/iNvh3PtgrS+urB+oU+/9Ey0hzzkisOR2nEfznYNigW8\n' +
    '=MNsu\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);
  clearSign =
    '-----BEGIN PGP SIGNED MESSAGE-----\n' +
    'Hash: SHA256\n' +
    '\n' +
    'hello world 2048 dsa\n' +
    '-----BEGIN PGP SIGNATURE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'iF4EAREIAAYFAlJ8LrcACgkQcvZy0yMm+1J03QD/UP5mMFvhxiKDo+x05hkfdr+E\n' +
    'tols/YXM1Bbuo1FyuUgA/2DXGQ/0TXohP9ugN6zEy3bxZ6Z8p6yDw3DiO9fa4Q7w\n' +
    '=B1zR\n' +
    '-----END PGP SIGNATURE-----';
  parsed = e2e.openpgp.asciiArmor.parseClearSign(clearSign);
  var signaturePacket = e2e.openpgp.parse.parseSerializedPacket(parsed.signature);
  assertTrue(signaturePacket.verify(e2e.stringToByteArray(parsed.body),
                                    publicKeyBlock.keyPacket.cipher,
                                    parsed.hash));
  assertFalse(signaturePacket.verify(e2e.stringToByteArray('bad world new'),
                                     publicKeyBlock.keyPacket.cipher));

  publicKeyAscii =  // 3072bit DSA key
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    '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\n' +
    '=E1LA\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);
  clearSign =
    '-----BEGIN PGP SIGNED MESSAGE-----\n' +
    'Hash: SHA256\n' +
    '\n' +
    'hello world dsa 3072\n' +
    '-----BEGIN PGP SIGNATURE-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'iF4EAREIAAYFAlJ8MmwACgkQp6zqceNWk7CBBQD9G+bUnNDBSg6xUAVzEeBGS1sJ\n' +
    'B9Dep8loLFgcHlLqoigA+wSFa2sn9pvAY5ReGCVr/O185wFLF5ZasweBSbgwMmwA\n' +
    '=0TM7\n' +
    '-----END PGP SIGNATURE-----';
  parsed = e2e.openpgp.asciiArmor.parseClearSign(clearSign);
  var signaturePacket = e2e.openpgp.parse.parseSerializedPacket(parsed.signature);
  assertTrue(signaturePacket.verify(e2e.stringToByteArray(parsed.body),
                                    publicKeyBlock.keyPacket.cipher,
                                    parsed.hash));
  assertFalse(signaturePacket.verify(e2e.stringToByteArray('bad world new'),
                                     publicKeyBlock.keyPacket.cipher));
}


function testElGamal() {
  var plaintext = 'hello world from encrypted message';
  var plaintextFilename = 'file.txt';
  var publicKeyAscii =  // Vint Cerf key with DSA key and ElGamal subkey
      '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
      '\n' +
      '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\n' +
      '=4QTq\n' +
      '-----END PGP PUBLIC KEY BLOCK-----';
  publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);

  var literal = new e2e.openpgp.packet.LiteralData(
      e2e.openpgp.packet.LiteralData.Format.TEXT,
      e2e.stringToByteArray(plaintextFilename),
      1375136046,
      e2e.stringToByteArray(plaintext)
      );
  asyncTestCase.waitForAsync('Waiting for encryption.');
  e2e.openpgp.block.EncryptedMessage.construct(
      literal,
      [publicKeyBlock.subKeys[0]])
    .addCallback(function(block) {
      asyncTestCase.continueTesting();
    }).addErrback(function(e) {
      fail(e);
    });;
}

function testEncryptionWithSignatures() {
  var plaintext = 'hello world from encrypted message';
  var privateKeyAscii =
    '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    '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\n' +
    '1KwNtVw=\n' +
    '=wHzz\n' +
    '-----END PGP PRIVATE KEY BLOCK-----';

  var publicKeyAscii =
    '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
    'Version: GnuPG v1.4.11 (GNU/Linux)\n' +
    '\n' +
    'mI0EUcy6DgEEAJb0T7gQlfKQWmR0dLUrueRMVy8UemcmxsdIH30/HqJvqO6xU0lK\n' +
    'NaFtaVxBdenAMpEooi1EcTi/bOKfz36FY/FARTiXv1LXuLzFJdPyjTYjh7tw+uOP\n' +
    'UlLJCTZikgrnM07txTUiVVEetOa+unyKn17EX0PlSpAbGZedyO0nGwXzABEBAAG0\n' +
    'BnRlc3QgNIi4BBMBAgAiBQJRzLoOAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX\n' +
    'gAAKCRAG/5ysCS2oCL2SA/9EV9j3T/TM3VRD0NvNySHodcxCP1BF0zm/M84I/WHQ\n' +
    'sGKmHStfCqqEGruB8E6NHQMJwNp1TzcswuxE0wiTJiXKe3w3+GZhPHdW5zcgiMKK\n' +
    'YLn80Tk6fUMx1zVZtXlSBYCN5Op/axjQRyb+fGnXOhmboqQodYaWS7qhJWQJilH6\n' +
    'iriNBFHMug4BBADDTMshHtyYhLmWC7793FlOFl5tkcEfdFKJRm30k/9yky4cuz//\n' +
    'Xe4uXM72SaTI1Dfi6UIz5ZuFTxw3bnAXav+SV4Q4dZo0hb4jU8YaQfDL4TsRp7uO\n' +
    '6iqxd8nlsh9JnBKE6Fk/CW5FoMZZ3/yEm3pq924Uv2AZlO6dafgXecyqNQARAQAB\n' +
    'iJ8EGAECAAkFAlHMug4CGwwACgkQBv+crAktqAhENwQAkMY/nds36KgzwfMPpxtB\n' +
    'aq8GbrUqY1r8lBl6a/bi8qeOuEgQmIxM2OpVPtL04c1c1hLflPCi1SQUlCIh3DkE\n' +
    'GQIcy0/wxUZdCvZK0mF5nZSq6tez3CwqbeOA4nBOLwbxho50VqxBpR4qypYrB2ip\n' +
    'ykxlwiqudEe0sE2b1KwNtVw=\n' +
    '=nHBL\n' +
    '-----END PGP PUBLIC KEY BLOCK-----';
  var publicKeyBlock = e2e.openpgp.block.factory.parseAscii(publicKeyAscii);
  var privateKeyBlock = e2e.openpgp.block.factory.parseAscii(
        privateKeyAscii);

  var passphrase = e2e.stringToByteArray('test');
  privateKeyBlock.keyPacket.cipher.unlockKey(passphrase);
  var literal = new e2e.openpgp.packet.LiteralData(
      e2e.openpgp.packet.LiteralData.Format.TEXT,
      e2e.stringToByteArray(''),  // file name
      new Date().getTime() / 1000,  // time date in seconds since 1970
      e2e.stringToByteArray(plaintext)
      );

  assertEquals(publicKeyBlock.subKeys[0], publicKeyBlock.getKeyToEncrypt());
  assertEquals(privateKeyBlock.keyPacket, privateKeyBlock.getKeyToSign());

  asyncTestCase.waitForAsync('Waiting for encryption.');

  e2e.openpgp.block.EncryptedMessage
    .construct(
      literal,
      [publicKeyBlock.getKeyToEncrypt()],
      [],
      privateKeyBlock.getKeyToSign())
    .addCallback(function(block) {
      var ascii = e2e.openpgp.asciiArmor.encode(block.header,
                                                    block.serialize());
      // Decrypt the message.
      var messageBlock = e2e.openpgp.block.factory.parseAscii(ascii);

      var encryptedToKeyId = messageBlock.eskPackets[0].keyId;
      var decryptionKey = privateKeyBlock.packets[3];
      assertArrayEquals(encryptedToKeyId, decryptionKey.keyId);
      decryptionKey.cipher.unlockKey(passphrase);
      asyncTestCase.waitForAsync('Waiting for session key decryption.');
      messageBlock.eskPackets[0]
        .decryptSessionKey(decryptionKey.cipher.getKey())
        .addCallback(function(ok) {
          asyncTestCase.continueTesting();
          assertTrue(ok);
          // We go through message parsing again because of b/10950199
          messageBlock.encryptedData.decrypt(messageBlock.eskPackets[0].symmetricAlgorithm,
                                                    messageBlock.eskPackets[0].getSessionKey());
          var decryptedBlocks = e2e.openpgp.block.factory.parseByteArrayMulti(
              messageBlock.encryptedData.data);
          // Check that only a single block was encrypted.
          assertEquals(1, decryptedBlocks.length);
          // And it was compressed.
          assertTrue(decryptedBlocks[0] instanceof e2e.openpgp.block.Compressed);

          // And it was a LiteralMessage.
          var decompressed = decryptedBlocks[0].getBlock();
          assertTrue(decompressed instanceof e2e.openpgp.block.LiteralMessage);

          // Message was decompressed correctly.
          assertEquals(
            e2e.byteArrayToString(decompressed.getData().data),
            plaintext);
          // And signature verifies correctly.
          var verifyResult = decompressed.verify([publicKeyBlock]);
          assertEquals(verifyResult.success.length, 1);
          assertEquals(verifyResult.failure.length, 0);
        }).addErrback(function(e) {
          fail(e);
        });
    }).addErrback(function(e) {
      fail(e);
    });
}
</script>
